package com.bright.hxj.cwduijie.service.impl;

import com.bright.hxj.cwduijie.enums.DataApi;
import com.bright.hxj.cwduijie.enums.OpType;
import com.bright.hxj.cwduijie.enums.SJJHBZ;
import com.bright.hxj.cwduijie.pojo.bo.ApiDataCollection;
import com.bright.hxj.cwduijie.pojo.dto.CheckResultDto;
import com.bright.hxj.cwduijie.pojo.po.AccSet;
import com.bright.hxj.cwduijie.pojo.query.DuijieQuery;
import com.bright.hxj.cwduijie.repository.AccSetRepository;
import com.bright.hxj.cwduijie.service.AbstractPerThousandApiService;
import com.bright.ghj.common.util.ListUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Function;

@Component
@RequiredArgsConstructor
@Slf4j
public class ApiAccSetServiceImpl extends AbstractPerThousandApiService<AccSet> {

    private final AccSetRepository accSetRepository;

    @Override
    public JpaSpecificationExecutor getJpaSpecificationExecutor() {
        return accSetRepository;
    }

    @Override
    public DataApi getDataApi() {
        return DataApi.ACC_SET;
    }

    @Override
    public Function<AccSet, Integer> getIdFunc() {
        return AccSet::getId;
    }

//    @Override
//    public List<String> getNeedDuijieZtDataKeys() {
//        List<AccSet> accSetBySjjhbz = accSetRepository.getAccSetBySjjhbz(SJJHBZ.WAITING.getValue());
//        accSetBySjjhbz.addAll(accSetRepository.getAccSetBySjjhbz(SJJHBZ.ERROR.getValue()));
//        return ListUtil.toSingleList(accSetBySjjhbz, AccSet::getDATA_KEY);
//    }

    @Override
    public Function<AccSet, String> getDataKeyFunc() {
        return AccSet::getDATA_KEY;
    }

    @Override
    public Function<ApiDataCollection, List<AccSet>> getDataFunc() {
        return null;
    }

    @Override
    protected void getData(ApiDataCollection apiDataCollection, DuijieQuery duijieQuery) {
        AccSet accSet = accSetRepository.getAccSetByDATAKEY(duijieQuery.getZtDataKey());
        if (accSet != null &&
                (accSet.getOpType() == null || accSet.getOpType() == OpType.ADD_OR_EDIT.getValue())
                && (accSet.getSjjhbz() == SJJHBZ.WAITING.getValue() || accSet.getSjjhbz() == SJJHBZ.ERROR.getValue()) ) {
            apiDataCollection.setAccSet(accSet);
        } else {
            apiDataCollection.setAccSet(null);
        }
    }

    @Override
    protected void checkDataValid(Map<String, CheckResultDto> checkResultDtoMap, ApiDataCollection apiDataCollection) {
        AccSet accSet = apiDataCollection.getAccSet();
        if (accSet != null) {
            CheckResultDto checkResultDto = checkService.checkSingleDataCommon(accSet);
            checkService.addErrorMsgs(checkResultDtoMap, checkResultDto, getDataApi(), Collections.singletonList(accSet.getId()));
        }
    }

    @Override
    public void sendData(ApiDataCollection apiDataCollection, DuijieQuery duijieQuery, String batchId) throws JsonProcessingException {
        AccSet accSet = apiDataCollection.getAccSet();

        List<AccSet> accSetDtos = new ArrayList<>();
        if (accSet == null) {
            log.debug("无法查询到账套数据，该接口跳过，账套标识：" + duijieQuery.getZtDataKey());
        } else {
            // 如果当前账套已经推过 也不用推
            Integer sjjhbz = accSet.getSjjhbz();
            if (sjjhbz == SJJHBZ.SUCCESS.getValue() || sjjhbz == SJJHBZ.EXECUTING.getValue() || sjjhbz == SJJHBZ.FEEDBACK_BUT_NOT_CHECK_COMPLETE.getValue()) {
                log.debug("该账套已经成功推送，该接口跳过，账套标识：" + duijieQuery.getZtDataKey());
            } else {
                accSetDtos.add(accSet);
            }
        }

        sendListData(accSetDtos, ListUtil.toSingleList(accSetDtos, AccSet::getId), batchId, duijieQuery.getAccSet());

        saveSendDataKeys(accSetDtos, AccSet::getDATA_KEY);


    }

    @Override
    protected List<AccSet> getNeedDeleteData(DuijieQuery duijieQuery) {
        // 将账套删除放到外面 批量调用 减少数据库查询次数
//        AccSet accSet = accSetRepository.getAccSetByDATAKEY(duijieQuery.getZtDataKey());
//        if (accSet.getOpType() == OpType.DEL.getValue() && (accSet.getSjjhbz() == SJJHBZ.WAITING.getValue() || accSet.getSjjhbz() == SJJHBZ.ERROR.getValue())) {
//            return Collections.singletonList(accSet);
//        }
        return Collections.emptyList();
    }

    @Override
    public DataApi getDeleteDataApi() {
        return DataApi.DELETE_ACC_SET;
    }

    // 批量删除账套的方法 供直接调用
    public void sendAccSetDelete(List<String> needDuijieZtDataKeys) {
        DuijieQuery duijieQuery = new DuijieQuery();
        duijieQuery.setZtDataKeys(needDuijieZtDataKeys);
        duijieQuery.setOpType(OpType.DEL);
        List<AccSet> needDeleteAccSets = dataManager.getAccSetsByDataKeys(duijieQuery);

        // 分个调用删除
        for (AccSet needDeleteAccSet : needDeleteAccSets) {
            try {
                Map<String, Object> deleteMap = new HashMap<>();
                deleteMap.put("DATA_KEYS", Collections.singletonList(needDeleteAccSet.getDATA_KEY()));
                sendMapData(deleteMap, getDeleteDataApi(), Collections.singletonList(needDeleteAccSet.getId()), needDeleteAccSet.getDATA_KEY(), needDeleteAccSet.getAccSet());
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }
        }
        saveDeletedDataKeys(getDeleteDataApi(), ListUtil.toSingleList(needDeleteAccSets, AccSet::getDATA_KEY));

    }

    @Override
    public List<Integer> getDataIds(ApiDataCollection apiDataCollection) {
        AccSet accSet = apiDataCollection.getAccSet();
        return accSet == null ? Collections.emptyList() : Collections.singletonList(accSet.getId());
    }
}
